<?php

use Illuminate\Support\HtmlString;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

if (!function_exists('set_hashId')) {
    /**
     * @param $id
     * @param string $salt
     * @param int $minLength
     * @param string $alphabet
     * @return string
     */
    function set_hashId($id, $salt = '', $minLength = 8, $alphabet = '')
    {
        $salt = $salt ? : config('app.key');

        if (empty($alphabet)) {
            $hash = new \Hashids\Hashids($salt, $minLength);
        } else {
            $hash = new \Hashids\Hashids($salt, $minLength, $alphabet);
        }

        return $hash->encode($id);
    }
}

if (!function_exists('get_hashId')) {
    /**
     * @param $hashId
     * @param string $salt
     * @param int $minLength
     * @param string $alphabet
     * @return int|false
     */
    function get_hashId($hashId, $salt = '', $minLength = 8, $alphabet = '')
    {
        $salt = $salt ? : config('app.key');

        if (empty($alphabet)) {
            $hash = new \Hashids\Hashids($salt, $minLength);
        } else {
            $hash = new \Hashids\Hashids($salt, $minLength, $alphabet);
        }

        return head($hash->decode($hashId));
    }
}

if (!function_exists('rsa_public_field')) {
    /**
     * 获取前端加密公钥
     * @return string
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
     */
    function rsa_public_field()
    {
        $filename = env('FORM_PUBLIC_KEY');
        $content = Storage::disk('local')->exists($filename)
            ? Storage::disk('local')->get($filename)
            : '';

        return new HtmlString('<input type="hidden" name="_rsa" id="_rsa" value="' . $content . '">');
    }
}

if (!function_exists('rsa_public_key')) {
    /**
     * 获取前端加密公钥
     * @return string
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
     */
    function rsa_public_key()
    {
        $filename = env('FORM_PUBLIC_KEY');
        $content = Storage::disk('local')->exists($filename)
            ? Storage::disk('local')->get($filename)
            : '';

        return $content;
    }
}

if (!function_exists('header_format')) {
    /**
     * @param int $errorCode
     * @param string $errorMsg
     * @return array
     */
    function header_format($errorCode = 0, $errorMsg = '')
    {
        $headers['X-' . config('app.name') . '-ErrorCode'] = $errorCode;
        $headers['X-' . config('app.name') . '-ErrorDesc'] = urlencode($errorMsg);
        return $headers;
    }
}
if (!function_exists('body_format')) {
    /**
     * @param int $errorCode
     * @param string $errorMsg
     * @return array
     */
    function body_format($errorCode = 0, $errorMsg = '')
    {
        return [
            'error'      => $errorCode ? true : false,
            'error_code' => $errorCode,
            'error_desc' => (string) $errorMsg,
        ];
    }
}
if (!function_exists('api_response')) {
    /**
     * @param mixed $data
     * @return \Illuminate\Http\JsonResponse
     */
    function api_response($data = null)
    {
        $headers = header_format(0);
        if (request()->has("enc_data")) {
            $data = base64_encode(json_encode($data));
        }
        $body = array_merge(body_format(0), ['data' => $data]);

        // 写入日志
        $request = request();
        $debug_id = uniqid();
        if (config('app.debug')) {
            $body['debug_id'] = $debug_id;
        }
        Log::debug($debug_id, [
            'LOG_ID'         => $debug_id,
            'IP_ADDRESS'     => $request->ip(),
            'REQUEST_URL'    => $request->fullUrl(),
            'REQUEST_METHOD' => $request->method(),
            'HEADERS'        => $request->header(),
            'PARAMETERS'     => $request->all(),
            'RESPONSES'      => $body
        ]);

        return response()->json($body)->withHeaders($headers);
    }
}

if (!function_exists('is_mobile')) {
    /*
     *  检查字符串是否为手机号码
     *  如 13500000000
     * @return 0 or 1
     */
    function is_mobile($str)
    {
        return preg_match('/^1([345789]\d{9})$/', $str);
    }
}

if (!function_exists('is_wxBrowser')) {
    /**
     * 判断是否是微信浏览器
     * @return bool
     */
    function is_wxBrowser()
    {
        return strpos($_SERVER["HTTP_USER_AGENT"], 'MicroMessenger');
    }
}

if (!function_exists('set_payCode')) {
    /**
     * @param $uid
     * @return string
     */
    function set_payCode(int $uid)
    {
        $uniqid = uniqid();
        $salt = strtolower($uniqid) . config('app.key');
        $set_hashId = set_hashId($uid, $salt, '', 'QWERTYUIOPLKJHGFDSAZXCVBNM');
        $payCode = 'V1' . strtoupper($uniqid) . $set_hashId;
        $tags = config('vica.pay.code_prefix') . $uid;
        \Illuminate\Support\Facades\Cache::tags($tags)->flush();
        \Illuminate\Support\Facades\Cache::tags($tags)->put($payCode, $uid, now()->addMinutes(1));
        return $payCode;
    }
}

if (!function_exists('get_payCode')) {
    /**
     * @param $code
     * @return int|bool
     */
    function get_payCode($code)
    {
        $uniqid = substr($code, 2, 13);
        $hashId = substr($code, 15);
        $salt = strtolower($uniqid) . config('app.key');
        if (!$uid = get_hashId($hashId, $salt, '', 'QWERTYUIOPLKJHGFDSAZXCVBNM')) {
            return false;
        }
        $tags = config('vica.pay.code_prefix') . $uid;
        $value = \Illuminate\Support\Facades\Cache::tags($tags)->pull($code);
        if ($value != $uid) {
            return false;
        }
        return $uid;
    }
}
/**
 * 生成订单号
 * @param string $prefix
 * @return string
 */
/*if (!function_exists('generate_orderNo')) {
    function generate_orderNo($prefix = '')
    {
        list($s, $t) = explode(' ', microtime());
        $mtime = substr(str_replace(array('.', ''), array('', ''), $t . $s), - 8, 3);
        $utime = substr($t, - 5);
//        $utime = $t - strtotime(date('Ymd 0:0:0'));
        $str = 'ABCDEFHJKLNPRSTUVXYZ';//
        $strRand = mt_rand(0, strlen($str) - 1);
        return $prefix . date('ydm') . mt_rand(10, 99) . $utime . $mtime . $str{$strRand};
    }
}*/

if (!function_exists('num_rand')) {
    /**
     * 生成随机数字
     * @param int $length
     * @return string
     */
    function num_rand($length = 6)
    {
        $output = '';
        for ($i = 0; $i < $length; $i ++) {
            $output .= mt_rand(0, 9);
        }
        return $output;
    }
}

if (!function_exists('check_app_sign')) {
    /**
     * @param Illuminate\Http\Request $request
     * @param string $key
     * @return bool
     */
    function check_app_sign($request, $key)
    {
        $params = $request->all();
        ksort($params);
        $buff = '';
        foreach ($params as $k => $v) {
            if ($k != 'sign' && $v != '' && !is_array($v)) {
                $buff .= $k . '=' . $v . '&';
            }
        }
        $string = trim($buff, "&") . '&key=' . $key;
        return $request->input('sign') == md5($string);
    }
}

if (!function_exists('get_app_ua')) {
    /**
     * @return string
     */
    function get_app_ua()
    {
        return request()->header('X-' . config('app.name') . '-UserAgent') ? : '';
    }
}


if (!function_exists('mosaic_phone')) {
    /**
     * 给手机号打码
     * @param string $phone
     * @return mixed|string
     */
    function mosaic_phone(string $phone)
    {
        $phone = substr_replace($phone, '****', 3, 4);
        return $phone;
    }
}

if (!function_exists('mosaic_bankcard')) {
    /**
     * 给银行卡打码
     * @param string $bankcard
     * @return bool|string
     */
    function mosaic_bankcard($bankcard)
    {
        return '**** **** **** ' . substr($bankcard, - 4);
    }
}

if (!function_exists('mosaic_name')) {
    /**
     * 给真实姓名打码
     * @param string $name
     * @return bool|string
     */
    function mosaic_name(string $name)
    {
        return '*' . mb_substr($name, - 1);
    }
}

if (!function_exists('mosaic_identity')) {
    /**
     * 给身份证号打码
     * @param string $identity
     * @return bool|string
     */
    function mosaic_identity(string $identity)
    {
        return substr($identity, 0, 1) . '****************' . substr($identity, - 1);
    }
}

if (!function_exists('mosaic_account')) {
    /**
     * 给账户打码
     * @param string $account
     * @return bool|string
     * @author czb
     */
    function mosaic_account(string $account)
    {
        return substr($account, 0, 3) . '****' . substr($account, - 4);
    }
}

if (!function_exists('alipay_encrypt')) {
    /**
     * 加密方法
     * @param string $str
     * @return string
     * @author cyz
     */
    function alipay_encrypt($str, $screct_key)
    {
        //AES, 128 模式加密数据 CBC
        $screct_key = base64_decode($screct_key);
        $str = trim($str);
        $str = alipay_addPKCS7Padding($str);
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), 1);
        $encrypt_str = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $screct_key, $str, MCRYPT_MODE_CBC);
        return base64_encode($encrypt_str);
    }
}

if (!function_exists('alipay_decrypt')) {
    /**
     * 解密方法
     * @param string $str
     * @return string
     * @author cyz
     */
    function alipay_decrypt($str, $screct_key)
    {
        //AES, 128 模式加密数据 CBC
        $str = base64_decode($str);
        $screct_key = base64_decode($screct_key);
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), 1);
        $encrypt_str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $screct_key, $str, MCRYPT_MODE_CBC);
        $encrypt_str = trim($encrypt_str);
        $encrypt_str = alipay_stripPKSC7Padding($encrypt_str);
        return $encrypt_str;
    }
}

if (!function_exists('alipay_addPKCS7Padding')) {
    /**
     * 填充算法
     * @param string $source
     * @return string
     * @author cyz
     */
    function alipay_addPKCS7Padding($source)
    {
        $source = trim($source);
        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $pad = $block - (strlen($source) % $block);
        if ($pad <= $block) {
            $char = chr($pad);
            $source .= str_repeat($char, $pad);
        }
        return $source;
    }
}

if (!function_exists('alipay_stripPKSC7Padding')) {
    /**
     * 移去填充算法
     * @param string $source
     * @return string
     * @author cyz
     */
    function alipay_stripPKSC7Padding($source)
    {
        $source = trim($source);
        $char = substr($source, - 1);
        $num = ord($char);
        if ($num == 62) return $source;
        $source = substr($source, 0, - $num);
        return $source;
    }
}

if (!function_exists('check_idcard')) {
    function check_idcard($idCard)
    {
        $idCard = (string) $idCard;
        $pattern = '/(?:^\d{15}$)|(?:^\d{18}$)|^\d{17}[\dXx]$/';
        if (!preg_match($pattern, $idCard)) {
            return false;
        }
        if (strlen($idCard) == 18) {
            $idCardWi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);//将前17位加权因子保存在数组里
            $idCardY = array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); //这是除以11后，可能产生的11位余数、验证码，也保存成数组
            $idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
            for ($i = 0; $i < 17; $i ++) {
                $idCardWiSum += substr($idCard, $i, 1) * $idCardWi[$i];
            }

            $idCardMod = $idCardWiSum % 11;        //计算出校验码所在数组的位置
            $idCardLast = substr($idCard, 17, 1);    //得到最后一位身份证号码

            //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
            if ($idCardMod == 2) {
                if ($idCardLast == "X" || $idCardLast == "x") {
                    return true;
                } else {
                    return false;
                }
            } else {

                //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                if ($idCardLast == $idCardY[$idCardMod]) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
}

if (!function_exists('photo_domain')) {
    /**
     * 图片链接
     * @param int $type
     * @param string $img
     * @return bool|string
     * @author czb
     */
    function photo_domain(string $img, int $type = 1)
    {
        switch ($type) {
            case 1 : // 七牛云
                $domain = 'http://' . config("filesystems.disks.qiniu.domains.default") . "/" . $img;
                break;
            default:
                $domain = $img;
                break;
        }
        return $domain;
    }
}

/**
 * 检验数据的真实性，并且获取解密后的明文.
 * @param $encryptedData string 加密的用户数据
 * @param $iv string 与用户数据一同返回的初始向量
 * @param $data string 解密后的原文
 *
 * @return int 成功0，失败返回对应的错误码
 */
if (!function_exists('decryptData')) {
    function wechat_decryptData($appid, $sessionKey, $encryptedData, $iv, &$data)
    {
        $OK = 0;
        $IllegalAesKey = - 41001;
        $IllegalIv = - 41002;
        $IllegalBuffer = - 41003;
        if (strlen($sessionKey) != 24) {
            return $IllegalAesKey;
        }
        $aesKey = base64_decode($sessionKey);


        if (strlen($iv) != 24) {
            return $IllegalIv;
        }
        $aesIV = base64_decode($iv);

        $aesCipher = base64_decode($encryptedData);

        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

        $dataObj = json_decode($result);
        if ($dataObj == NULL) {
            return $IllegalBuffer;
        }
        if ($dataObj->watermark->appid != $appid) {
            return $IllegalBuffer;
        }
        $data = $result;

        return $OK;
    }
}

/**
 * 返回门卫
 *
 * @author cwc
 */
if (!function_exists('get_model_for_guard')) {
    function get_model_for_guard(string $guard)
    {
        return collect(config('auth.guards'))
            ->map(function ($guard) {
                if (!isset($guard['provider'])) {
                    return false;
                }

                return config("auth.providers.{$guard['provider']}.model");
            })->get($guard);
    }
}

/**
 * 判断框架信息
 *
 * @author cwc
 */
if (!function_exists('is_not_lumen')) {
    function is_not_lumen(): bool
    {
        return !preg_match('/lumen/i', app()->version());
    }
}

